package com.chen.cloudpicture.manager.websocket.disruptor;

import com.chen.cloudpicture.manager.websocket.model.PictureEditRequestMessage;
import com.chen.cloudpicture.model.entity.User;
import lombok.Data;
import org.springframework.web.socket.WebSocketSession;

/**
 * 图片编辑事件（要处理的事件类型/要接收的参数）
 * <p>
 * 扩展：使用 disruptor 框架优化性能。
 * 当前 websocket 接受消息和处理消息使用的是同一线程，如果有大量消息要处理可能会花费很长时间，’
 * 如果此时有大量客户端同时连接，并发非常大可能就会耗尽资源让新客户端无法连接（一台 tomcat 服务器默认支持 200 个线程）
 * 这时可以让接受消息和处理消息分离/解耦，websocket连接只负责接受消息，然后另开专门的线程异步执行处理消息任务。
 * 其实上述操作异步执行 + 任务队列获取任务，使用线程池就可以实现了，但对于协同编辑场景，需要尽可能保持低延迟。
 * <p>
 * Disruptor 无锁队列可以在高并发场景下保持极低延迟和高吞吐量，还有优雅停机机制，在任务队列中所有任务执行完后再退出服务，防止任务丢失。
 * disruptor：是一个高性能的并发框架，是无锁的环形队列，专门解决高吞吐量和低延迟场景的高并发问题。也支持生产者-消费者模式，可以作为消息队列使用。
 * （与 rabbitmq 等相比最突出的就是极低的延迟，宣传说是纳秒级别。另外它只是一个框架，是单机的，不是中间件）
 * 主要特点是环形缓冲区：使用固定大小的数组，避免了频繁内存分配和垃圾回收的性能损耗。用序号表示每一个事件，取模存放，
 * 存储事件有一个环形缓冲区，消费者读取执行事件也相当于有一个缓冲区，如果当前索引位置上已经存储事件了，当存储位置慢于读取位置时才会覆盖原先的事件，
 * 如果存储位置追上读取位置（生产者追上消费者）就不会继续存储，而是等待，防止未执行的消息被覆盖。
 * 没有锁，基于 CAS 进行并发控制。适用于高频实时消息处理场景，金融场景等。
 * 与传统常用的 ArrayBlockingQueue 相比，最重要的/（disruptor 的核心特性）就是无锁 CAS，环形缓冲区固定大小数组，消息生产的序号控制以及防止数据覆盖的机制
 */
@Data
public class PictureEditEvent {

    /**
     * 消息
     */
    private PictureEditRequestMessage pictureEditRequestMessage;

    /**
     * 当前用户的 session
     */
    private WebSocketSession session;

    /**
     * 当前用户
     */
    private User user;

    /**
     * 图片 id
     */
    private Long pictureId;

}
